package com.atguigu.gmall.activity.controller;

import com.atguigu.gmall.activity.service.SeckillGoodsService;
import com.atguigu.gmall.activity.util.CacheHelper;
import com.atguigu.gmall.activity.util.DateUtil;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.result.ResultCodeEnum;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.common.util.AuthContextHolder;
import com.atguigu.gmall.common.util.MD5;
import com.atguigu.gmall.model.activity.SeckillGoods;
import com.atguigu.gmall.model.activity.UserRecode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.ReactiveSubscription;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @author: 李旭
 * @create: 2021-09-17 15:31
 * <p>
 * 秒杀商品
 **/
@RestController
@RequestMapping("/api/activity/seckill")
public class SeckillGoodsApiController {

    @Autowired
    private SeckillGoodsService seckillGoodsService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RabbitService rabbitService;

    //秒杀频道页面 秒杀商品集合
    @GetMapping("/list")
    public List<SeckillGoods> getSeckillGoodsList() {
        return seckillGoodsService.getSeckillGoodsList();
    }

    //根据skuId查询一个秒杀商品
    @GetMapping("/getItem/{skuId}")
    public SeckillGoods getItem(@PathVariable String skuId) {
        return seckillGoodsService.getItem(skuId);
    }


    //获取抢购码
    @GetMapping("/auth/getSeckillSkuIdStr/{skuId}")
    public Result getSeckillSkuIdStr(@PathVariable String skuId, HttpServletRequest request) {
        //1:是否在活动范围之内  时间
        SeckillGoods item = seckillGoodsService.getItem(skuId);
        Date startTime = item.getStartTime();
        Date endTime = item.getEndTime();
        //开始时间小于 当前时间   大于结束时间
        Calendar instance = Calendar.getInstance();
        Date curTime = instance.getTime();
        //开始时间小于等于当前时间
        //当前时间大于等于开始时间   //结束时间大于当前时间
        if (!DateUtil.dateCompare(startTime, curTime) || DateUtil.dateCompare(endTime, curTime)) {
            return Result.fail().message("此秒杀商品已过期");
        }
        //2:是否还有剩余库存
        Long size = redisTemplate.opsForList().size(RedisConst.SECKILL_STOCK_PREFIX + skuId);
        if (size <= 0) {
            return Result.fail().message("此秒杀商品已抢完");
        }
        String userId = AuthContextHolder.getUserId(request);
        //生成抢购码
        String encrypt = MD5.encrypt(userId);
        return Result.ok(encrypt);
    }

    //开始秒杀
    @PostMapping("/auth/seckillOrder/{skuId}")
    public Result seckillOrder(@PathVariable Long skuId, String skuIdStr, HttpServletRequest request) {
        //1、校验抢购码
        String userId = AuthContextHolder.getUserId(request);
        if (StringUtils.isEmpty(skuIdStr) || !MD5.encrypt(userId).equals(skuIdStr)) {
            return Result.build(null, ResultCodeEnum.SECKILL_ILLEGAL);
        }
        //2、校验状态位
        Object status = CacheHelper.get(skuId.toString());
        if (!"1".equals(status)) {
            return Result.build(null, ResultCodeEnum.SECKILL_FINISH);
        }
        UserRecode userRecode = new UserRecode();
        userRecode.setUserId(userId);
        userRecode.setSkuId(skuId);
        //3.发消息
        rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_Seckill, MqConst.ROUTING_SECKILL_1, userRecode);
        //4.Result
        return Result.ok();
    }

    //第3s执行一次查询秒杀结果
    @GetMapping("/auth/checkOrder/{skuId}")
    public Result checkOrder(@PathVariable Long skuId, HttpServletRequest request) {
        String userId = AuthContextHolder.getUserId(request);
        //1、此用户是否已经有订单了
        //秒杀商品前缀
/*        public static final String SECKILL_GOODS = "seckill:goods";
        public static final String SECKILL_ORDERS = "seckill:orders:";
        public static final String SECKILL_ORDERS_USERS = "seckill:orders:users:";
        public static final String SECKILL_STOCK_PREFIX = "seckill:stock:";
        public static final String SECKILL_USER = "seckill:user:";*/
        Object r1 = redisTemplate.opsForValue().get(RedisConst.SECKILL_ORDERS_USERS + userId);
        if (null != r1) {
            return Result.build(null, ResultCodeEnum.SECKILL_ORDER_SUCCESS);
        }
        //2、此用户是否抢购成功
        Object r2 = redisTemplate.opsForValue().get(RedisConst.SECKILL_ORDERS + userId);
        if (null != r2) {
            //2.1成功
            return Result.build(null, ResultCodeEnum.SECKILL_SUCCESS);
        }
        //3.用户是否来过
        Object r3 = redisTemplate.opsForValue().get(RedisConst.SECKILL_USER + userId);
        if (null != r3) {
           //来过了
            //此用户是否抢购成功
            Object r5 = redisTemplate.opsForValue().get(RedisConst.SECKILL_ORDERS + userId);
            if (null != r5) {
                //2.1成功
                return Result.build(null, ResultCodeEnum.SECKILL_SUCCESS);
            }else{
                return Result.build(null, ResultCodeEnum.SECKILL_FAIL);//抢单失败
            }
        }else{
            //没来过了
            //3.1校验状态位
            Object r4 = CacheHelper.get(skuId.toString());
            if("1".equals(r4)){
                return Result.build(null, ResultCodeEnum.SECKILL_RUN);//正在排队中
            }else{
                //无货
                return Result.build(null, ResultCodeEnum.SECKILL_FAIL);//抢单失败
            }
        }
    }


}
